<template>
  <div class="form-single-fragment" style="position: relative;">
    <vxe-toolbar>
      <template v-slot:buttons>
        <el-button type="primary" icon="el-icon-plus" size="small" @click="onAddDatasourceClick">新增数据表</el-button>
      </template>
    </vxe-toolbar>
    <el-table :data="getPageDatasourceTableList" border header-cell-class-name="table-header-gray" size="small" :header-cell-style="{background:'#f4f4f4', color:'#717171' }">
      <el-table-column label="序号" header-align="center" align="center" type="index" width="55px" />
      <el-table-column label="数据表名" prop="tableName" min-width="150px" />
      <el-table-column label="关联类型" prop="relationType" width="100px">
        <template slot-scope="scope">
          <el-tag size="mini" :type="getDatasourceTableTagType(scope.row.relationType)" effect="dark">
            {{ getDatasourceTableTagName(scope.row.relationType) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="主表关联字段" prop="masterColumnName" width="120px" />
      <el-table-column label="从表关联字段" prop="slaveColumnName" width="120px" />
      <el-table-column label="级联删除" prop="cascadeDelete" align="center" width="80px">
        <template slot-scope="scope">
          <el-tag v-if="scope.row.relationType != null" size="mini" :type="scope.row.cascadeDelete ? 'success' : 'danger'" effect="dark">
            {{ scope.row.cascadeDelete ? '是' : '否' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="左连接" prop="leftJoin" align="center" width="80px">
        <template slot-scope="scope">
          <el-tag v-if="scope.row.relationType != null" size="mini" :type="scope.row.leftJoin ? 'success' : 'danger'" effect="dark">
            {{ scope.row.leftJoin ? '是' : '否' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="220px" fixed="right">
        <template slot-scope="scope">
          <!-- 数据源主表只有当没有任何关联的时候才可以编辑 -->
          <el-button
            class="table-btn success"
            size="small"
            type="text"
            :disabled="scope.row.relationType == null && Array.isArray(scope.row.relationList) && scope.row.relationList.length > 0"
            @click="onEditDatasourceTable(scope.row)"
          >编辑</el-button>
          <el-button size="small" type="text" @click="onEditTableColumn(scope.row)">字段管理</el-button>
          <el-button size="small" type="text" :disabled="scope.row.relationType != null" @click="onEditVirtualColumn(scope.row)">聚合计算</el-button>
          <el-button
            class="table-btn delete"
            size="small"
            type="text"
            :disabled="scope.row.relationType == null && (!Array.isArray(scope.row.relationList) || scope.row.relationList.length <= 0)"
            @click="onDeleteDatasourceTable(scope.row)"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import '@/components/Dialog'
import '@/staticDict/onlineStaticDict.js'
import { findItemFromList } from '@/utils'
/* eslint-disable-next-line */
import rules from '@/utils/validate.js'
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin } from '@/core/mixins'
import OnlinePageTableColumnRule from './onlinePageTableColumnRule.vue'
import OnlinePageVirtualColumn from './onlinePageVirtualColumn.vue'
import EditOnlinePageDatasource from './editOnlinePageDatasource.vue'
import EditOnlinePageDatasourceRelation from './editOnlinePageDatasourceRelation.vue'
import {
  OnlinePageController,
  OnlineDblinkController,
  OnlineDatasourceController,
  OnlineDatasourceRelationController,
  OnlineDictController
} from '@/api/onlineController.js'

export default {
  name: 'EditFormDataMode',
  mixins: [uploadMixin, statsDateRangeMixin],
  props: {
    pageId: {
      type: String,
      default: undefined
    }
  },
  data() {
    return {
      // 页面数据模型列表
      pageDatasourceList: [],
      // 数据库信息
      dblinkInfo: {},
      dictList: [],
      formRules: {
        pageCode: [
          { required: true, message: '页面编码不能为空！', trigger: 'blur' },
          { type: 'string', pattern: /^[A-Za-z0-9]+$/, message: '页面编码只允许输入字母和数字', trigger: 'blur' }
        ],
        pageName: [
          { required: true, message: '页面名称不能为空！', trigger: 'blur' }
        ]
      },
      clientHeight: this.$store.getters.clientHeight,
      currentTable: undefined,
      virtualColumnTable: undefined
    }
  },
  computed: {
    isEdit() {
      return this.pageId != null && this.pageId !== ''
    },
    getPageDatasource() {
      return this.pageDatasourceList[0]
    },
    getPageDatasourceTableList() {
      if (this.getPageDatasource == null) return []
      console.log(JSON.stringify(this.getPageDatasource))
      const tableList = []
      // 添加主表信息
      tableList.push({
        id: this.getPageDatasource.datasourceId,
        tableName: this.getPageDatasource.masterTableIdDictMap.name,
        tableId: this.getPageDatasource.masterTableId,
        relationType: undefined,
        masterColumnName: undefined,
        slaveColumnName: undefined,
        cascadeDelete: false,
        leftJoin: false,
        tag: this.getPageDatasource
      })
      // 添加关联从表信息
      if (Array.isArray(this.getPageDatasource.relationList)) {
        this.getPageDatasource.relationList.forEach(relation => {
          tableList.push({
            id: relation.relationId,
            tableName: relation.slaveTable.tableName,
            tableId: relation.slaveTableId,
            relationType: relation.relationType,
            masterColumnName: (relation.masterColumn || {}).columnName || '未知字段',
            slaveColumnName: (relation.slaveColumn || {}).columnName || '未知字段',
            cascadeDelete: relation.cascadeDelete,
            leftJoin: relation.leftJoin,
            tag: relation
          })
        })
      }
      return tableList
    }
  },
  watch: {
  },
  mounted() {
    this.loadOnlineDictList().catch(e => {})
    this.loadDblinkList().then(res => {
      return this.initPageDatasourceInfo(this.pageId)
    }).catch(e => {})
  },
  methods: {
    onCancel(isSuccess) {
      if (this.observer != null) {
        this.observer.cancel(isSuccess)
      }
    },
    /**
     * 获取数据库信息
     */
    loadDblinkList() {
      return new Promise((resolve, reject) => {
        this.dblinkInfo = {}
        OnlineDblinkController.list({}).then(res => {
          res.data.dataList.forEach(item => {
            this.dblinkInfo[item.dblinkId] = {
              ...item,
              tableList: undefined
            }
          })
          resolve()
        }).catch(e => {
          reject(e)
        })
      })
    },
    /**
     * 获取数据模型关联信息
     */
    loadDatasourceRelation() {
      if (this.getPageDatasource == null) return Promise.resolve()
      // alert(JSON.stringify(this.getPageDatasource))
      return OnlineDatasourceRelationController.list({
        onlineDatasourceRelationDtoFilter: {
          datasourceId: this.getPageDatasource.datasourceId
        }
      })
    },
    /**
     * 初始化页面数据模型信息
     */
    initPageDatasourceInfo(pageId) {
      return new Promise((resolve, reject) => {
        OnlinePageController.listOnlinePageDatasource({
          pageId: pageId
        }).then(res => {
          this.pageDatasourceList = res.data.dataList
          // alert(JSON.stringify(this.pageDatasourceList))
          return this.loadDatasourceRelation()
        }).then(res => {
          this.pageDatasourceList = this.pageDatasourceList.map(item => {
            if (item.datasourceId === this.getPageDatasource.datasourceId) {
              item.relationList = res.data.dataList || []
            }
            return item
          })

          resolve()
        }).catch(e => {
          reject(e)
        })
      })
    },
    /** ***********************************************************
     ************************ 数据模型操作 ************************
     *************************************************************/
    getDatasourceTableTagType(relationType) {
      if (relationType == null) return 'success'
      switch (relationType) {
        case this.SysOnlineRelationType.ONE_TO_ONE: return 'primary'
        case this.SysOnlineRelationType.ONE_TO_MANY: return 'warning'
        default:
          return 'info'
      }
    },
    getDatasourceTableTagName(relationType) {
      if (relationType == null) return '数据主表'
      return this.SysOnlineRelationType.getValue(relationType) || '未知类型'
    },
    /**
     * 新增数据模型表
     */
    onAddDatasourceClick() {
      if (this.getPageDatasource == null) {
        // 新增数据模型
        this.$dialog.show('新建数据源', EditOnlinePageDatasource, {
          area: '500px'
        }, {
          pageId: this.pageId,
          dblinkInfo: this.dblinkInfo
        }).then(res => {
          return this.initPageDatasourceInfo(this.pageId)
        }).catch(e => {})
      } else {
        // 新增数据模型关联
        this.loadDatasourceValidTableList(this.getPageDatasource).then(res => {
          this.$dialog.show('添加关联', EditOnlinePageDatasourceRelation, {
            area: '600px'
          }, {
            datasource: this.getPageDatasource,
            dblinkInfo: this.dblinkInfo[this.getPageDatasource.dblinkId],
            usedTableNameList: this.getPageDatasourceTableList.map(item => item.tableName)
          }).then(res => {
            return this.initPageDatasourceInfo(this.pageId)
          }).catch(e => {
            console.log(e)
          })
        }).catch(e => {
          console.log(e)
        })
      }
    },
    /**
     * 编辑数据模型表
     */
    onEditDatasourceTable(row) {
      this.loadDatasourceValidTableList(this.getPageDatasource).then(res => {
        if (row.relationType == null) {
          // 编辑数据模型
          this.$dialog.show('编辑数据源', EditOnlinePageDatasource, {
            area: '500px'
          }, {
            pageId: this.pageId,
            dblinkInfo: this.dblinkInfo,
            datasourceId: row.tag.datasourceId
          }).then(res => {
            return this.initPageDatasourceInfo(this.pageId)
          }).catch(e => {})
        } else {
          // 编辑关联
          this.$dialog.show('编辑关联', EditOnlinePageDatasourceRelation, {
            area: '600px'
          }, {
            relationId: row.id,
            datasource: this.getPageDatasource,
            dblinkInfo: this.dblinkInfo[this.getPageDatasource.dblinkId],
            usedTableNameList: this.getPageDatasourceTableList.map(item => item.tableName)
          }).then(res => {
            return this.initPageDatasourceInfo(this.pageId)
          }).catch(e => {
            console.log(e)
          })
        }
      }).catch(e => {})
    },
    /**
     * 删除数据模型表
     */
    onDeleteDatasourceTable(row) {
      if (row.relationType == null) {
        // 删除数据模型
        let warningMsg = '是否删除此数据模型？'
        if (Array.isArray(row.relationList) && row.relationList.length > 0) {
          warningMsg = '此数据模型下还存在关联，如果删除关联数据也将同时删除，是否继续？'
        }
        this.$confirm(warningMsg).then(res => {
          const params = {
            datasourceId: row.id
          }
          return OnlineDatasourceController.delete(params)
        }).then(res => {
          return this.initPageDatasourceInfo(this.pageId)
        }).catch(e => {})
      } else {
        // 删除关联数据
        this.$confirm('是否删除此关联数据？').then(res => {
          const params = {
            relationId: row.id
          }

          return OnlineDatasourceRelationController.delete(params)
        }).then(res => {
          return this.initPageDatasourceInfo(this.pageId)
        }).catch(e => {})
      }
    },
    /**
     * 获取数据库下数据表列表
     */
    loadDblinkTableList(dblinkId) {
      return new Promise((resolve, reject) => {
        // 如果此数据库下数据表已经获取过，直接返回数据表列表
        if (Array.isArray(this.dblinkInfo[dblinkId].tableList) && this.dblinkInfo[dblinkId].tableList.length > 0) {
          resolve(this.dblinkInfo[dblinkId].tableList)
          return
        }
        // 获取数据库下数据表列表
        OnlineDblinkController.listDblinkTables({
          dblinkId: dblinkId
        }).then(res => {
          this.dblinkInfo[dblinkId].tableList = res.data.dataList
          resolve(res.data)
        }).catch(e => {
          reject(e)
        })
      })
    },
    /**
     * 获取本数据源下所有导入的表
     */
    loadDatasourceTableList(datasourceId) {
      return new Promise((resolve, reject) => {
        const params = {
          datasourceId: datasourceId
        }
        OnlineDatasourceController.view(params).then(res => {
          this.datasourceTableList = res.data.tableList || []
          resolve(this.datasourceTableList)
        }).catch(e => {
          reject(e)
        })
      })
    },
    loadOnlineDictList() {
      return new Promise((resolve, reject) => {
        OnlineDictController.list({}).then(res => {
          this.dictList = res.data.dataList
          resolve()
        }).catch(e => {
          reject(e)
        })
      })
    },
    /**
     * 获得数据源所有可用的数据表列表，包含已经导入的数据表和未导入的数据表
     */
    loadDatasourceValidTableList(datasource) {
      if (datasource == null) return Promise.reject()
      if (Array.isArray(datasource.validTableList) && datasource.validTableList.length > 0) {
        return Promise.resolve()
      }
      const httpCalls = [
        this.loadDatasourceTableList(datasource.datasourceId),
        this.loadDblinkTableList(datasource.dblinkId)
      ]

      return new Promise((resolve, reject) => {
        Promise.all(httpCalls).then(res => {
          const datasourceTableList = res[0]
          const dblinkTableList = res[1]
          // 合并两个数据表
          let tableNameSet = new Set()
          datasource.validTableList = dblinkTableList.map(table => {
            tableNameSet.add(table.tableName)
            const temp = findItemFromList(datasourceTableList, table.tableName, 'tableName')
            tableNameSet.add(table.tableName)
            return {
              id: temp ? temp.tableId : table.tableName,
              name: table.tableName,
              desc: temp ? temp.tableComment : table.tableComment,
              status: temp ? this.SysOnlinePageDatasourceFieldStatus.USED : this.SysOnlinePageDatasourceFieldStatus.UNUSED,
              dblinkTable: temp == null,
              tag: temp || table
            }
          })
          // 添加被使用但是已经从数据库中删除的数据表
          datasourceTableList.forEach(table => {
            if (!tableNameSet.has(table.tableName)) {
              datasource.validTableList.push({
                id: table.tableId,
                name: table.tableName,
                desc: table.tableComment,
                status: this.SysOnlinePageDatasourceFieldStatus.DELETED,
                dblinkTable: false,
                tag: table
              })
            }
          })
          tableNameSet = null
          resolve()
        }).catch(e => {
          reject(e)
        })
      })
    },
    /**
     * 关闭字段规则编辑
     */
    onRuleClose() {
      this.currentTable = undefined
    },
    /**
     * 字段管理
     */
    onEditTableColumn(row) {
      this.currentTable = row
      // 编辑字段管理
      this.$dialog.show('字段管理', OnlinePageTableColumnRule, {
        area: ['1100px', '600px']
      }, {
        isMasterTable: this.currentTable.relationType == null,
        tableId: this.currentTable.tableId,
        dblinkId: this.getPageDatasource.dblinkId,
        tableName: this.currentTable.tableName,
        dictList: this.dictList,
        height: 520
      }).catch(e => {})
    },
    /**
     * 关闭聚合计算管理
     */
    onVirtualColumnClose() {
      this.virtualColumnTable = undefined
    },
    /**
     * 编辑数据源虚拟字段
     */
    onEditVirtualColumn(row) {
      this.virtualColumnTable = row
      // 编辑字段管理
      this.$dialog.show('聚合计算', OnlinePageVirtualColumn, {
        area: ['1100px', '600px']
      }, {
        datasource: this.virtualColumnTable.tag,
        relationList: this.virtualColumnTable.tag.relationList,
        height: 520
      }).catch(e => {})
    }
  }
}
</script>

<style  lang="scss">
  .form-single-fragment {
    display: flex;

    flex-direction: column;
    margin: 10px 10px 20px 10px;
    .blueLink {
      color: #409eff;
      font-size: 14px;
      margin-left: 20px;
      cursor: pointer;
    }
    .btnList {
      margin-top:20px;
      display: flex;
      justify-content: right;
      float: right;
      .submitBtn {
        margin-right: 30px;
      }
    }
    .fromFlex {
      height: 36px;
      display: flex;
      align-items: center;
    }
    .base-info {
      display: flex;
      margin-bottom: 20px;
      .basics-info {
        width: 100%;
      }
    }
  }
</style>
